package cn.stylefeng.guns.modular.hx.storage.controller;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.stylefeng.guns.modular.basic.entity.BasicCustomer;
import cn.stylefeng.guns.modular.basic.entity.BasicPutgoods;
import cn.stylefeng.guns.modular.basic.service.BasicPutgoodsService;
import cn.stylefeng.guns.modular.hx.basic.entity.HxBasicGoods;
import cn.stylefeng.guns.modular.hx.basic.service.HxBasicGoodsService;
import cn.stylefeng.guns.modular.hx.dps.entity.DpsZcServer;
import cn.stylefeng.guns.modular.hx.dps.service.DpsZcServerService;
import cn.stylefeng.guns.modular.hx.order.model.params.HxOrderOutParam;
import cn.stylefeng.guns.modular.hx.order.model.result.HxOrderOutResult;
import cn.stylefeng.guns.modular.hx.storage.entity.Numbers;
import cn.stylefeng.guns.modular.hx.storage.model.vo.DpsMidOrdersCVo;
import cn.stylefeng.guns.modular.hx.storage.model.vo.KhBqpringtVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.fasterxml.jackson.databind.ObjectMapper;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.base.shiro.annotion.Permission;
import cn.stylefeng.guns.core.util.DateUtil;
import cn.stylefeng.guns.core.util.QRCodeUtil;
import cn.stylefeng.guns.modular.basic.service.BasicCustomerService;
import cn.stylefeng.guns.modular.basic.service.BasicWarehouseService;
import cn.stylefeng.guns.modular.hx.storage.entity.HxStorageOut;
import cn.stylefeng.guns.modular.hx.storage.entity.HxStorageOutDetailed;
import cn.stylefeng.guns.modular.hx.storage.model.params.HxStorageOutDetailedParam;
import cn.stylefeng.guns.modular.hx.storage.model.params.HxStorageOutParam;
import cn.stylefeng.guns.modular.hx.storage.model.result.HxStorageOutDetailedResult;
import cn.stylefeng.guns.modular.hx.storage.model.result.HxStorageOutResult;
import cn.stylefeng.guns.modular.hx.storage.service.HxStorageOutDetailedService;
import cn.stylefeng.guns.modular.hx.storage.service.HxStorageOutService;
import cn.stylefeng.guns.sys.modular.system.entity.User;
import cn.stylefeng.guns.sys.modular.system.service.UserService;
import cn.stylefeng.roses.core.base.controller.BaseController;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import cn.stylefeng.roses.core.util.ToolUtil;


/**
 * 拣货单表控制器
 *
 * @author zhucx
 * @Date 2023-09-05 16:05:54
 */
@Controller
@RequestMapping("/hxStorageOut")
public class HxStorageOutController extends BaseController {

    private String PREFIX = "/hx/storage/hxStorageOut";
    private String PREFIX2 = "/hx/storage/hxPersonStatistics";

    @Autowired
    private HxStorageOutService hxStorageOutService;

    @Autowired
    private UserService userService;

    @Autowired
    private BasicCustomerService basicCustomerService;

    @Autowired
    private BasicWarehouseService basicWarehouseService;

    @Autowired
    private HxStorageOutDetailedService hxStorageOutDetailedService;

    @Autowired
    private BasicPutgoodsService basicPutgoodsService;

    @Autowired
    private DpsZcServerService dpsZcServerService;

    @Autowired
    private HxBasicGoodsService hxBasicGoodsService;

    /**
     * 跳转到主页面
     *
     * @author lww
     * @Date 2023-11-09
     */
    @RequestMapping("/hxPersonStatistics")
    public String hxPersonStatistics(Model model) {

        User user = userService.getcurrentUser();
        Long deptId = user.getDeptId();
        Long deliverId = user.getDeliverId();
        model.addAttribute("basicCustomerList", basicCustomerService.findAvailableList(deptId, deliverId, user.getOperateId()));

        return PREFIX2 + "/hxPersonStatistics.html";
    }

    /**
     * 拣货人统计
     *
     * @author lww
     * @Date 2023-11-09
     */
    @ResponseBody
    @RequestMapping("/storageUser")
    public LayuiPageInfo storageuser(HxStorageOutParam hxStorageOutParam, String condition, String startTime, String endTime) {

        if (ToolUtil.isNotEmpty(startTime) && ToolUtil.isNotEmpty(endTime)) {
            hxStorageOutParam.setTimeInterval("'" + startTime + "' and '" + endTime + "'");
        } else if (startTime == null && endTime == null) {
            hxStorageOutParam.setTimeInterval("'" + DateUtil.getDate() + "' and '" + DateUtil.getDate() + "'");
        }
        String[] StorageState = {"待复核", "复核中", "已完成"};
        hxStorageOutParam.setStorageState1(StorageState);
        User user = userService.getcurrentUser();
        hxStorageOutParam.setDeptId(user.getDeptId());
        hxStorageOutParam.setOperateId(user.getOperateId());
        return this.hxStorageOutService.findstorageuser(hxStorageOutParam, condition);
    }

    /**
     * 出库质检信息统计
     *
     * @author lww
     * @Date 2023-11-15
     */
    @ResponseBody
    @RequestMapping("/qualityUser")
    public LayuiPageInfo qualityuser(HxStorageOutParam hxStorageOutParam, String condition, String startTime, String endTime) {
        User user = userService.getcurrentUser();
        if (ToolUtil.isNotEmpty(startTime) && ToolUtil.isNotEmpty(endTime)) {
            hxStorageOutParam.setTimeInterval("'" + startTime + "' and '" + endTime + "'");
        } else if (startTime == null && endTime == null) {
            hxStorageOutParam.setTimeInterval("'" + DateUtil.getDate() + "' and '" + DateUtil.getDate() + "'");
        }
        hxStorageOutParam.setStorageState("已完成");
        hxStorageOutParam.setDeptId(user.getDeptId());
        hxStorageOutParam.setOperateId(user.getOperateId());
        return this.hxStorageOutService.findqualityuser(hxStorageOutParam, condition);
    }


    /**
     * 跳转到主页面
     *
     * @author zhucx
     * @Date 2023-09-05
     */
    @RequestMapping("")
    public String index(Model model) {
        User user = userService.getcurrentUser();
        Long deptId = user.getDeptId();
        Long deliverId = user.getDeliverId();
        //查询可选择仓库
        model.addAttribute("basicWarehouseList", basicWarehouseService.findAvailableList(deptId, deliverId, user.getOperateId()));
        //查询可选择客户
        model.addAttribute("customerlist", basicCustomerService.findAvailableList(deptId, deliverId, user.getOperateId()));
        return PREFIX + "/hxStorageOut.html";
    }

    /**
     * 新增页面
     *
     * @author zhucx
     * @Date 2023-09-05
     */
    @RequestMapping("/add")
    public String add() {
        return PREFIX + "/hxStorageOut_add.html";
    }

    /**
     * 编辑页面
     *
     * @author zhucx
     * @Date 2023-09-05
     */
    @RequestMapping("/edit")
    public String edit() {
        return PREFIX + "/hxStorageOut_edit.html";
    }

    /**
     * 新增接口
     *
     * @author zhucx
     * @Date 2023-09-05
     */
    @RequestMapping("/addItem")
    @ResponseBody
    public ResponseData addItem(HxStorageOutParam hxStorageOutParam) {
        this.hxStorageOutService.add(hxStorageOutParam);
        return ResponseData.success();
    }

    /**
     * 编辑接口
     *
     * @author zhucx
     * @Date 2023-09-05
     */
    @RequestMapping("/editItem")
    @ResponseBody
    public ResponseData editItem(HxStorageOutParam hxStorageOutParam) {
        this.hxStorageOutService.update(hxStorageOutParam);
        return ResponseData.success();
    }

    /**
     * 删除接口
     *
     * @author zhucx
     * @Date 2023-09-05
     */
    @RequestMapping("/delete")
    @ResponseBody
    public ResponseData delete(HxStorageOutParam hxStorageOutParam) {
        this.hxStorageOutService.delete(hxStorageOutParam);
        return ResponseData.success();
    }

    /**
     * 查看详情接口
     *
     * @author zhucx
     * @Date 2023-09-05
     */
    @RequestMapping("/detail")
    @ResponseBody
    public ResponseData detail(HxStorageOutParam hxStorageOutParam) {
        HxStorageOut detail = this.hxStorageOutService.getById(hxStorageOutParam.getId());
        return ResponseData.success(detail);
    }

    @RequestMapping("/btnEditPrint")
    @ResponseBody
    public ResponseData btnEditPrint(Integer[] ids) {
        for (Integer id : ids) {
            HxStorageOutParam hxStorageOutParam = new HxStorageOutParam();
            hxStorageOutParam.setId(id);
            this.hxStorageOutService.updatePrint2(hxStorageOutParam);
        }
        return ResponseData.success();
    }

    /**
     * 批量打印出库订单  页面
     */
    @RequestMapping("print")
    public String print() {
        return PREFIX + "/print.html";
    }

    /**
     * 打印查询
     * 出库订单信息
     */
    @ResponseBody
    @RequestMapping("/getPrintStorageOut")
    public HxStorageOutResult getPrintOrderPut(String[] storageNumbers) {
        User user = userService.getcurrentUser();
        HxStorageOutParam hxStorageOutParam = new HxStorageOutParam();
        hxStorageOutParam.setStorageNumber(storageNumbers[0]);
        HxStorageOutResult printStorageOut = hxStorageOutService.getPrintStorageOut(hxStorageOutParam);
        HxStorageOutParam param = new HxStorageOutParam();
//        for (String storageNumber : storageNumbers) {
//            param.setStorageNumber(storageNumber);
//            this.hxStorageOutService.updatePrint(param);
//        }
        printStorageOut.setPrintName(user.getName());
        return printStorageOut;
    }

    /**
     * 更新打印次数
     *
     * @return
     */
    @ResponseBody
    @RequestMapping("/getPrintStorageOut2")
    public ResponseData getPrintOrderPut2(String[] storageNumbers) {
        HxStorageOutParam param = new HxStorageOutParam();
        for (String storageNumber : storageNumbers) {
            param.setStorageNumber(storageNumber);
            this.hxStorageOutService.updatePrint(param);
        }
        return ResponseData.success();
    }

    /**
     * 打印查询
     * 出库单明细信息
     */
    @ResponseBody
    @RequestMapping("/getPrintStorageOutDetailed")
    public List<HxStorageOutDetailedResult> getPrintOrderPutDetailed(String[] storageNumbers) {
        HxStorageOutDetailedParam HxStorageOutDetailedParam = new HxStorageOutDetailedParam();
        HxStorageOutDetailedParam.setStorageNumber1(storageNumbers);
        List<HxStorageOutDetailedResult> list = hxStorageOutDetailedService.findListBySpec2(HxStorageOutDetailedParam);
        List<HxStorageOutDetailedResult> res = new ArrayList<HxStorageOutDetailedResult>();
        String goodsBigtype = "";
        for (HxStorageOutDetailedResult r : list) {
            if (goodsBigtype == "") {
                if (ToolUtil.isNotEmpty(r.getGoodsBigtype())) {
                    goodsBigtype = r.getGoodsBigtype();
                    HxStorageOutDetailedResult put = new HxStorageOutDetailedResult();
                    put.setGoodsNumber(r.getGoodsBigtype());
                    res.add(put);
                    res.add(r);
                } else {
                    res.add(r);
                }
            } else {
                if (ToolUtil.isNotEmpty(r.getGoodsBigtype())) {
                    if (goodsBigtype.equals(r.getGoodsBigtype())) {
                        res.add(r);
                    } else {
                        goodsBigtype = r.getGoodsBigtype();
                        HxStorageOutDetailedResult put = new HxStorageOutDetailedResult();
                        put.setGoodsNumber(r.getGoodsBigtype());
                        res.add(put);
                        res.add(r);
                    }
                } else {
                    res.add(r);
                }
            }
        }
        return res;
    }

    /**
     * 跳转打印标签页面
     */
    @RequestMapping("/tobtnqrCode")
    public String tobtnqrCode() {
        return PREFIX + "/btnqrCode.html";
    }

    /**
     * 跳转打印标签页面
     */
    @RequestMapping("/tobtnqrCode1")
    public String tobtnqrCode1() {
        return PREFIX + "/btnqrCode1.html";
    }

    /**
     * 跳转打印DPS箱码页面
     */
    @RequestMapping("/tobtnDpsXm")
    public String tobtnDpsXm() {
        return PREFIX + "/btnDpsXm.html";
    }

    /**
     * 跳转打印DPS箱码页面
     */
    @RequestMapping("/tobtnKhbqXm")
    public String tobtnKhbqXm() {
        return PREFIX + "/btnKhbqXm.html";
    }

    /**
     * 查看详情接口
     */
    @RequestMapping("/details")
    @ResponseBody
    public ResponseData details(HxStorageOutParam hxStorageOutParam) {
        List<HxStorageOutResult> detail = this.hxStorageOutService.details(hxStorageOutParam); //按拣货单编号链接2表 根据id查出数据 再根据拣货单顺序从小到大排序
        //System.out.println(detail);
        return ResponseData.success(detail);
    }

    /**
     * 查看详情接口
     */
    @RequestMapping("/detailsDpsXm")
    @ResponseBody
    public ResponseData detailsDpsXm(HxStorageOutParam hxStorageOutParam) {
        List<HxStorageOutResult> detail = this.hxStorageOutService.details(hxStorageOutParam); //按拣货单编号链接2表 根据id查出数据 再根据拣货单顺序从小到大排序
        HxStorageOut hxStorageOut = this.hxStorageOutService.getById(hxStorageOutParam.getId());
        if (ToolUtil.isEmpty(hxStorageOut.getGetUnitNumber()) && ToolUtil.isNotEmpty(hxStorageOut.getGetUnitId())) {
            BasicPutgoods basicPutgoods = basicPutgoodsService.getById(hxStorageOut.getGetUnitId());
            hxStorageOut.setGetUnitNumber(basicPutgoods.getUnitNumber());
        }
        hxStorageOut.setCreateTime(new Date());
        return ResponseData.success(hxStorageOut);
    }

    /**
     * 创建条码
     */
    @RequestMapping(value = "/getDpsCode", method = RequestMethod.GET)
    @ResponseBody
    public void getDpsCode(String id, String name, HttpServletRequest request, HttpServletResponse response) {
        try {
            //logo
            File logoFile = new File("");
            String url = id;
            QRCodeUtil.drawLogoCode_128(logoFile, url, name, 350, 70, request, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 创建条码
     */
    @RequestMapping(value = "/getDpsCode1", method = RequestMethod.GET)
    @ResponseBody
    public void getDpsCode1(String id, String name, HttpServletRequest request, HttpServletResponse response) {
        try {
            //logo
            File logoFile = new File("");
            String url = id;
            QRCodeUtil.drawLogoCode_128(logoFile, url, name, 350, 30, request, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建条码
     */
    @RequestMapping(value = "/getDpsCode2", method = RequestMethod.GET)
    @ResponseBody
    public void getDpsCode2(String id, String name, HttpServletRequest request, HttpServletResponse response) {
        try {
            //logo
            File logoFile = new File("");
            String url = id;
            QRCodeUtil.drawLogoCode_128(logoFile, url, name, 200, 20, request, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成二维码
     */
    @RequestMapping(value = "/getqrcode1", method = RequestMethod.GET)
    @ResponseBody
    public void generateQRCode4Product1(Numbers fid, String name, HttpServletRequest request, HttpServletResponse response) {
        try {
            //logo
            File logoFile = new File("");
            // 使用Jackson库将对象转换为JSON字符串
            ObjectMapper objectMapper = new ObjectMapper();

            String json = objectMapper.writeValueAsString(fid);
            //System.out.println(json);
            String url = json;
            QRCodeUtil.drawLogoQRCode(logoFile, url, name, 320, 40, request, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 批量中止
     */
    @RequestMapping("/btnSuspension")
    @ResponseBody
    @Permission
    public ResponseData btnSuspension(Integer[] ids) {
        for (Integer id : ids) {
            HxStorageOut hxStorageOut = hxStorageOutService.getById(id);
            if (hxStorageOut.getStorageState().equals("待拣货") || hxStorageOut.getStorageState().equals("拣货中")) {
                HxStorageOutParam hxStorageOutParamUpdate = new HxStorageOutParam();
                hxStorageOutParamUpdate.setId(id);
                hxStorageOutParamUpdate.setStorageState("拣货中止");
                hxStorageOutService.update(hxStorageOutParamUpdate);

//    			hxStorageOutDetailedService.lambdaUpdate()
//    			.eq(HxStorageOutDetailed::getStorageNumber, hxStorageOut.getStorageNumber())
//    			.set(HxStorageOutDetailed::getStorageTime, null)
//    			.set(HxStorageOutDetailed::getPicked, null)
//    			.set(HxStorageOutDetailed::getRealNum, null)
//    			.update();
            } else {
                return ResponseData.error(hxStorageOut.getStorageNumber() + "单据已拣货无法中止！");
            }
        }
        return ResponseData.success();
    }

    @RequestMapping("/btnKhBqPrintXm")
    @ResponseBody
    public ResponseData btnKhBqPrintXm(String ids) {
        if(ToolUtil.isEmpty(ids)){
            return ResponseData.error("请选择要打印的拣货单");
        }

        List<HxStorageOut> hxStorageOutList = this.hxStorageOutService.lambdaQuery()
                .in(HxStorageOut::getId, ids.split(","))
                .list();

        if(ToolUtil.isEmpty(hxStorageOutList)){
            return ResponseData.error("请选择要打印的拣货单");
        }
        //
        Map<String,HxStorageOut> storageNumberMap = new HashMap<>();
        for(HxStorageOut obj : hxStorageOutList){
            storageNumberMap.put(obj.getStorageNumber(),obj);
        }

        // 查询拣货单涉及商品列表
        List<HxStorageOutDetailed> hxStorageOutDetailedList = this.hxStorageOutDetailedService.lambdaQuery()
                .in(HxStorageOutDetailed::getStorageNumber, storageNumberMap.keySet())
                .last(" order by storage_number, floor(position_pickingorder) asc ")
                .list();

        Set<Long> goodsIdSet = new HashSet<>();
        for(HxStorageOutDetailed obj : hxStorageOutDetailedList){
            goodsIdSet.add(obj.getGoodsId());
        }

        // 查询涉及商品对应的箱规
        List<HxBasicGoods> hxBasicGoodsList = this.hxBasicGoodsService.lambdaQuery()
                .in(HxBasicGoods::getId, goodsIdSet)
                .list();
        Map<String,HxBasicGoods> hxBasicGoodsMap = new HashMap<>();
        for(HxBasicGoods obj : hxBasicGoodsList){
            hxBasicGoodsMap.put(obj.getId().toString(),obj);
        }

        String dateS = DateUtil.getDateS();

        // 组箱
        KhBqpringtVo khBqpringtVoAdd = null;
        Map<String,List<KhBqpringtVo>> khBqprintMap = new HashMap<>();
        for(HxStorageOutDetailed obj : hxStorageOutDetailedList){
            HxStorageOut hxStorageOut = storageNumberMap.get(obj.getStorageNumber());
            KhBqpringtVo khBqpringtVo = new KhBqpringtVo();
            khBqpringtVo.setStorageNumber(obj.getStorageNumber());
            khBqpringtVo.setGetUnitNumber(hxStorageOut.getGetUnitNumber());
            khBqpringtVo.setGetUnit(hxStorageOut.getGetUnit());
            khBqpringtVo.setGoodsName(obj.getGoodsName());
            khBqpringtVo.setGoodsNumber(obj.getGoodsNumber());
            khBqpringtVo.setPositionNumber(obj.getPositionNumber());
            khBqpringtVo.setStockPort(hxStorageOut.getStockPort());
            khBqpringtVo.setNum(obj.getNum());
            khBqpringtVo.setCreateTime(dateS);
            khBqpringtVo.setNumSumStr(obj.getNum()+obj.getUnit());
            HxBasicGoods hxBasicGoods = hxBasicGoodsMap.get(obj.getGoodsId().toString());
            if(ToolUtil.isNotEmpty(hxBasicGoods) && ToolUtil.isNotEmpty(hxBasicGoods.getBoxSpecs())){
                try {
                    StringBuffer boxNumStr = null;
                    BigDecimal boxSpecs = new BigDecimal(hxBasicGoods.getBoxSpecs());
                    khBqpringtVo.setBoxSpecs(boxSpecs.toString());
                    if(ToolUtil.isNotEmpty(obj.getNum())){
                        BigDecimal zs = new BigDecimal(obj.getNum()).divide(boxSpecs, 0, RoundingMode.DOWN);
                        if(zs.compareTo(BigDecimal.ZERO) > 0){
                            for(int i = 0;i<zs.intValue();i++){
                                khBqpringtVoAdd = new KhBqpringtVo();
                                ToolUtil.copyProperties(khBqpringtVo, khBqpringtVoAdd);
                                khBqpringtVoAdd.setBoxNumStr( "1箱");
                                if(ToolUtil.isEmpty(khBqprintMap.get(obj.getStorageNumber()))){
                                    List<KhBqpringtVo> addList = new ArrayList<>();
                                    addList.add(khBqpringtVoAdd);
                                    khBqprintMap.put(obj.getStorageNumber(),addList);
                                }else{
                                    khBqprintMap.get(obj.getStorageNumber()).add(khBqpringtVoAdd);
                                }
                            }
                        }
                        BigDecimal ys = new BigDecimal(obj.getNum()).remainder(boxSpecs);
                        if(ys.compareTo(BigDecimal.ZERO) > 0){
                            khBqpringtVoAdd = new KhBqpringtVo();
                            ToolUtil.copyProperties(khBqpringtVo, khBqpringtVoAdd);
                            boxNumStr = new StringBuffer();
                            boxNumStr.append(ys.setScale(0,BigDecimal.ROUND_UP)).append(hxBasicGoods.getJibenUnit());
                            khBqpringtVoAdd.setBoxNumStr(boxNumStr.toString());
                            if(ToolUtil.isEmpty(khBqprintMap.get(obj.getStorageNumber()))){
                                List<KhBqpringtVo> addList = new ArrayList<>();
                                addList.add(khBqpringtVoAdd);
                                khBqprintMap.put(obj.getStorageNumber(),addList);
                            }else{
                                khBqprintMap.get(obj.getStorageNumber()).add(khBqpringtVoAdd);
                            }
                        }
                    }
                }catch (Exception e){
                }
            }
        }

        List<KhBqpringtVo> allKhBqpringtVoList = new ArrayList<>();
        for(String key : khBqprintMap.keySet()){
            allKhBqpringtVoList.addAll(khBqprintMap.get(key));
        }
        return ResponseData.success(allKhBqpringtVoList);
    }

    /**
     * 箱码
     * @param ids
     * @return
     */
    @RequestMapping("/btnKhBqPrintQian")
    @ResponseBody
    public ResponseData btnKhBqPrintQian(String ids) {

        if(ToolUtil.isEmpty(ids)){
            return ResponseData.error("请选择要打印的拣货单");
        }

        List<HxStorageOut> hxStorageOutList = this.hxStorageOutService.lambdaQuery()
                .in(HxStorageOut::getId, ids.split(","))
                .list();

        if(ToolUtil.isEmpty(hxStorageOutList)){
            return ResponseData.error("请选择要打印的拣货单");
        }
        //
        Set<String> storageNumberSet = new HashSet<>();
        for(HxStorageOut obj : hxStorageOutList){
            storageNumberSet.add(obj.getStorageNumber());
        }

        // 查询拣货单涉及商品列表
        List<HxStorageOutDetailed> hxStorageOutDetailedList = this.hxStorageOutDetailedService.lambdaQuery()
                .in(HxStorageOutDetailed::getStorageNumber, storageNumberSet)
                .list();
        Set<Long> goodsIdSet = new HashSet<>();
        for(HxStorageOutDetailed obj : hxStorageOutDetailedList){
            goodsIdSet.add(obj.getGoodsId());
        }

        // 查询涉及商品对应的箱规
        List<HxBasicGoods> hxBasicGoodsList = this.hxBasicGoodsService.lambdaQuery()
                .in(HxBasicGoods::getId, goodsIdSet)
                .list();
        StringBuffer errStr = new StringBuffer();
        for(HxBasicGoods obj : hxBasicGoodsList){
            if(ToolUtil.isEmpty(obj.getBoxSpecs())){
                errStr.append("[").append(obj.getGoodsNumber()).append("]");
                errStr.append(obj.getGoodsName());
                errStr.append("</br>");
            }
        }

        if(errStr.length() > 0){
            errStr.append("无箱规，请维护后重试！");
            return ResponseData.error(errStr.toString());
        }
        return ResponseData.success();
    }

    /**
     * 批量下发AGV拣货任务
     */
    @RequestMapping("/btnAgvStorage")
    @ResponseBody
    public ResponseData btnAgvStorage(Integer[] ids) {
        User user = userService.getcurrentUser();
        if (user.getOperateId() != null) {
            synchronized (user.getOperateId()) {
                return hxStorageOutService.btnAgvStorage(ids, user);
            }
        } else {
            return ResponseData.error("账号不支持下发AGV拣货任务");
        }
    }

    /**
     * 批量下发DPS拣货任务
     */
    @RequestMapping("/btnDpsStorage")
    @ResponseBody
    public ResponseData btnDpsStorage(Integer[] ids) {
        User user = userService.getcurrentUser();
        if (user.getOperateId() != null) {
            synchronized (user.getOperateId()) {
                if (ToolUtil.isEmpty(ids)) {
                    return ResponseData.error("请先选择要操作的记录！");
                }
                List<DpsZcServer> dpsZcServerList = dpsZcServerService.lambdaQuery()
                        .eq(DpsZcServer::getOperateId, user.getOperateId())
                        .eq(DpsZcServer::getWorkTyp,"摘果")
                        .list();
                Map<String,DpsZcServer> dpsZcServerMap = new HashMap<>();
                for(DpsZcServer obj : dpsZcServerList){
                    dpsZcServerMap.put(obj.getAreaId().toString(),obj);
                }

                List<HxStorageOut> hxStorageOuts = hxStorageOutService.lambdaQuery()
                        .in(HxStorageOut::getId, ids).list();
                BasicCustomer basicCustomer = null;
                Map<String, HxStorageOut> hxStorageOutMap = new HashMap<>();
                Map<String, Set<Integer>> storageIdMap = new HashMap<>();
                for (HxStorageOut obj : hxStorageOuts) {
                    hxStorageOutMap.put(obj.getStorageNumber(), obj);
                    if (basicCustomer == null) {
                        basicCustomer = basicCustomerService.getById(obj.getCustomerId());
                    }
                    if (!"拆零".equals(obj.getScattered())) {
                        return ResponseData.error("[" + obj.getStorageNumber() + "]不是拆零任务，无法操作");
                    }
                    if (!"待拣货".equals(obj.getStorageState())) {
                        return ResponseData.error("任务[" + obj.getStorageNumber() + "]状态不是[待拣货]，无法操作");
                    }
                    if (ToolUtil.isEmpty(obj.getStockPort())) {
                        return ResponseData.error("任务[" + obj.getStorageNumber() + "]请先分配集货位！");
                    }

                    Long areaId = obj.getAreaId();
                    if(ToolUtil.isEmpty(areaId)){
                        return ResponseData.error("拣货任务未指定库区，无法操作");
                    }

                    if(ToolUtil.isEmpty(dpsZcServerMap.get(areaId.toString()))){
                        return ResponseData.error("拣货任务指定库区未指定DPS数据库，无法操作");
                    }

                    if(storageIdMap.get(areaId.toString()) == null){
                        Set storageIdSet = new HashSet();
                        storageIdSet.add(obj.getId());
                        storageIdMap.put(areaId.toString(),storageIdSet);
                    }else{
                        storageIdMap.get(areaId.toString()).add(obj.getId());
                    }
                }

                //查找拣货明细
                List<HxStorageOutDetailed> hxStorageOutDetaileds = hxStorageOutDetailedService.lambdaQuery()
                        .in(HxStorageOutDetailed::getStorageNumber, hxStorageOutMap.keySet())
                        .list();
                String dateHour = DateUtil.getDateHour();
                Map<String, List<DpsMidOrdersCVo>> dpsMidOrdersCVoMap = new HashMap();
                for (HxStorageOutDetailed obj : hxStorageOutDetaileds) {
                    String stockPort = hxStorageOutMap.get(obj.getStorageNumber()).getStockPort();
                    Long areaId = hxStorageOutMap.get(obj.getStorageNumber()).getAreaId();

                    String shopid =String.valueOf(hxStorageOutMap.get(obj.getStorageNumber()).getGetUnitId());
                    if(ToolUtil.isNotEmpty(hxStorageOutMap.get(obj.getStorageNumber()).getGetUnitNumber())){
                        shopid = hxStorageOutMap.get(obj.getStorageNumber()).getGetUnitNumber();
                    }

                    DpsMidOrdersCVo dpsMidOrdersCVo = DpsMidOrdersCVo.builder()
                            .orderid(obj.getStorageNumber())
                            .sku(obj.getGoodsNumber())
                            .matchid(dateHour)
                            .quantity(new BigDecimal(obj.getNum()).intValue())
                            .tolocation(obj.getPositionNumber())
                            .area("C1")
                            .batchid(StringUtils.leftPad(stockPort, 3, "0"))
                            .state("0")
                            .downdate(DateUtil.getDateS())
                            .shopid(shopid)
                            .shopname(String.valueOf(hxStorageOutMap.get(obj.getStorageNumber()).getGetUnit()))
                            .discount(obj.getGoodsSpecs())
                            .barcode(obj.getGoodsPcode69())
                            .goodsname(obj.getGoodsName())
                            .wmsboxcode(obj.getStorageNumber())
                            .wmsorderid(obj.getId().toString())
                            .build();
                    if(ToolUtil.isNotEmpty(hxStorageOutMap.get(obj.getStorageNumber()).getGetUnitNumber())) {
                        dpsMidOrdersCVo.setShopid(hxStorageOutMap.get(obj.getStorageNumber()).getGetUnitNumber());
                    }
                    if(dpsMidOrdersCVoMap.get(areaId.toString()) == null){
                        List<DpsMidOrdersCVo> dpsMidOrdersCAddPList = new ArrayList<>();
                        dpsMidOrdersCAddPList.add(dpsMidOrdersCVo);
                        dpsMidOrdersCVoMap.put(areaId.toString(),dpsMidOrdersCAddPList);
                    }else{
                        dpsMidOrdersCVoMap.get(areaId.toString()).add(dpsMidOrdersCVo);
                    }
                }
                try {
                    StringBuffer errStr = new StringBuffer();
                    for(String key : dpsMidOrdersCVoMap.keySet()){
                        ResponseData responseData = hxStorageOutService.btnDpsStorage(dpsMidOrdersCVoMap.get(key), dpsZcServerMap.get(key), storageIdMap.get(key), user);
                        if(!responseData.getSuccess()){
                            errStr.append(responseData.getMessage()).append("</br>");
                        }
                    }
                    if(errStr.length() > 0){
                        return ResponseData.error(errStr.toString());
                    }else{
                        return ResponseData.success();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    return ResponseData.error(e.getMessage());
                }
            }
        } else {
            return ResponseData.error("账号不支持下发DPS拣货任务");
        }
    }

    /**
     * 批量下发AGV扫码拣货任务
     */
    @RequestMapping("/btnAgvStorageScan")
    @ResponseBody
    public ResponseData btnAgvStorageScan(Integer[] ids) {
        User user = userService.getcurrentUser();
        if (user.getOperateId() != null) {
            synchronized (user.getOperateId()) {
                return hxStorageOutService.btnAgvStorageScan(ids, user);
            }
        } else {
            return ResponseData.error("账号不支持下发AGV拣货任务");
        }
    }

    /**
     * 导出
     */
    @ResponseBody
    @RequestMapping("/listAll")
    public List<HxStorageOutResult> listAll(HxStorageOutParam hxStorageOutParam, String condition, String startTime, String endTime, String startTime2, String endTime2) {
        if (hxStorageOutParam != null && hxStorageOutParam.getGoodsNames() != null && hxStorageOutParam.getGoodsNames().length > 0) {
            for (int i = 0; i < hxStorageOutParam.getGoodsNames().length; i++) {
                if (hxStorageOutParam.getGoodsNames()[i] != null) { // 进一步检查数组元素是否为 null
                    hxStorageOutParam.getGoodsNames()[i] = hxStorageOutParam.getGoodsNames()[i].replace("& #40;", "(").replace("& #41;", ")");
                }
            }
        }
        User user = userService.getcurrentUser();
        hxStorageOutParam.setDeptId(user.getDeptId());
        hxStorageOutParam.setDeliverId(user.getDeliverId());
        if (ToolUtil.isEmpty(hxStorageOutParam.getTimeType())) {
            hxStorageOutParam.setTimeType("cj");
        }
        if (ToolUtil.isNotEmpty(startTime) && ToolUtil.isNotEmpty(endTime)) {
            hxStorageOutParam.setTimeInterval("'" + startTime + "' and '" + endTime + "'");
        } else if (startTime == null && endTime == null) {
            hxStorageOutParam.setTimeInterval("'" + DateUtil.getDate() + "' and '" + DateUtil.getDate() + "'");
        }
        if (ToolUtil.isNotEmpty(startTime2) && ToolUtil.isNotEmpty(endTime2)) {
            hxStorageOutParam.setTimeInterval2("'" + startTime2 + "' and '" + endTime2 + "'");
        }
        return this.hxStorageOutService.findlistAllBySpec(hxStorageOutParam, condition, user.getOperateId());
    }

    /**
     * 合计
     */
    @ResponseBody
    @RequestMapping("/count")
    public ResponseData count(HxStorageOutParam hxStorageOutParam, String condition, String startTime, String endTime, String startTime2, String endTime2) {
        if (hxStorageOutParam != null && hxStorageOutParam.getGoodsNames() != null && hxStorageOutParam.getGoodsNames().length > 0) {
            for (int i = 0; i < hxStorageOutParam.getGoodsNames().length; i++) {
                if (hxStorageOutParam.getGoodsNames()[i] != null) {
                    hxStorageOutParam.getGoodsNames()[i] = hxStorageOutParam.getGoodsNames()[i].replace("& #40;", "(").replace("& #41;", ")");
                }
            }
        }
        User user = userService.getcurrentUser();
        hxStorageOutParam.setDeptId(user.getDeptId());
        hxStorageOutParam.setDeliverId(user.getDeliverId());
        if (ToolUtil.isEmpty(hxStorageOutParam.getTimeType())) {
            hxStorageOutParam.setTimeType("cj");
        }
        if (ToolUtil.isNotEmpty(startTime) && ToolUtil.isNotEmpty(endTime)) {
            hxStorageOutParam.setTimeInterval("'" + startTime + "' and '" + endTime + "'");
        } else if (startTime == null && endTime == null) {
            hxStorageOutParam.setTimeInterval("'" + DateUtil.getDate() + "' and '" + DateUtil.getDate() + "'");
        }
        if (ToolUtil.isNotEmpty(startTime2) && ToolUtil.isNotEmpty(endTime2)) {
            hxStorageOutParam.setTimeInterval2("'" + startTime2 + "' and '" + endTime2 + "'");
        }
        HxStorageOutResult res = this.hxStorageOutService.count(hxStorageOutParam, condition, user.getOperateId());
        return ResponseData.success(res);
    }

    /**
     * 查询列表
     *
     * @author zhucx
     * @Date 2023-09-05
     */
    @ResponseBody
    @RequestMapping("/list")
    public LayuiPageInfo list(HxStorageOutParam hxStorageOutParam, String condition, String startTime, String endTime, String startTime2, String endTime2) {
        if (hxStorageOutParam != null && hxStorageOutParam.getGoodsNames() != null && hxStorageOutParam.getGoodsNames().length > 0) {
            for (int i = 0; i < hxStorageOutParam.getGoodsNames().length; i++) {
                if (hxStorageOutParam.getGoodsNames()[i] != null) { // 进一步检查数组元素是否为 null
                    hxStorageOutParam.getGoodsNames()[i] = hxStorageOutParam.getGoodsNames()[i].replace("& #40;", "(").replace("& #41;", ")");
                }
            }
        }

        User user = userService.getcurrentUser();
        hxStorageOutParam.setDeptId(user.getDeptId());
        if (ToolUtil.isEmpty(hxStorageOutParam.getTimeType())) {
            hxStorageOutParam.setTimeType("cj");
        }
        if (ToolUtil.isNotEmpty(startTime) && ToolUtil.isNotEmpty(endTime)) {
            hxStorageOutParam.setTimeInterval("'" + startTime + "' and '" + endTime + "'");
        } else if (startTime == null && endTime == null) {
            hxStorageOutParam.setTimeInterval("'" + DateUtil.getDate() + "' and '" + DateUtil.getDate() + "'");
        }
        if (ToolUtil.isNotEmpty(startTime2) && ToolUtil.isNotEmpty(endTime2)) {
            hxStorageOutParam.setTimeInterval2("'" + startTime2 + "' and '" + endTime2 + "'");
        }
        return this.hxStorageOutService.findPageBySpec(hxStorageOutParam, condition, user.getOperateId());
    }


    /**
     * 导出订单及明细
     *
     * @param hxStorageOutParam
     * @param condition
     * @param startTime
     * @param endTime
     * @throws IOException
     */
    @ResponseBody
    @RequestMapping("/exportToExcel")
    public void exportToExcel(HttpServletResponse response, HxStorageOutParam hxStorageOutParam, String condition, String startTime, String endTime, String startTime2, String endTime2) throws IOException {
        if (hxStorageOutParam != null && hxStorageOutParam.getGoodsNames() != null && hxStorageOutParam.getGoodsNames().length > 0) {
            for (int i = 0; i < hxStorageOutParam.getGoodsNames().length; i++) {
                if (hxStorageOutParam.getGoodsNames()[i] != null) { // 进一步检查数组元素是否为 null
                    hxStorageOutParam.getGoodsNames()[i] = hxStorageOutParam.getGoodsNames()[i].replace("& #40;", "(").replace("& #41;", ")");
                }
            }
        }
        User user = userService.getcurrentUser();
        hxStorageOutParam.setDeptId(user.getDeptId());
        if (ToolUtil.isEmpty(hxStorageOutParam.getTimeType())) {
            hxStorageOutParam.setTimeType("cj");
        }
        if (ToolUtil.isNotEmpty(startTime) && ToolUtil.isNotEmpty(endTime)) {
            hxStorageOutParam.setTimeInterval("'" + startTime + "' and '" + endTime + "'");
        } else if (startTime == null && endTime == null) {
            hxStorageOutParam.setTimeInterval("'" + DateUtil.getDate() + "' and '" + DateUtil.getDate() + "'");
        }
        if (ToolUtil.isNotEmpty(startTime2) && ToolUtil.isNotEmpty(endTime2)) {
            hxStorageOutParam.setTimeInterval2("'" + startTime2 + "' and '" + endTime2 + "'");
        }

        List<HxStorageOutResult> hxStorageOutResults = this.hxStorageOutService.expExcel(hxStorageOutParam, condition, user.getOperateId());
        XSSFWorkbook wb = new XSSFWorkbook();
        Sheet sheet = wb.createSheet("拣货单及明细");
        // 创建标题行
        Row titleRow = sheet.createRow(0);
        titleRow.createCell(0).setCellValue("集货口");
        titleRow.createCell(1).setCellValue("拣货单号");
        titleRow.createCell(2).setCellValue("收货客户编号");
        titleRow.createCell(3).setCellValue("收货客户名称");
        titleRow.createCell(4).setCellValue("是否拆零");
        titleRow.createCell(5).setCellValue("配送日");
        titleRow.createCell(6).setCellValue("拣货状态");
        titleRow.createCell(7).setCellValue("订单分拣时间");
        titleRow.createCell(8).setCellValue("订单分拣完成");
        titleRow.createCell(9).setCellValue("库区");
        titleRow.createCell(10).setCellValue("库位");
        titleRow.createCell(11).setCellValue("商品名称");
        titleRow.createCell(12).setCellValue("商品编码");
        titleRow.createCell(13).setCellValue("商品条码");
        titleRow.createCell(14).setCellValue("应拣数量");
        titleRow.createCell(15).setCellValue("实拣数量");
        titleRow.createCell(16).setCellValue("单位");
        titleRow.createCell(17).setCellValue("商品分拣时间");
        // 添加数据行
        int cnt = 1;
        for (HxStorageOutResult obj : hxStorageOutResults) {
            Row row = sheet.createRow(cnt);
            row.createCell(0).setCellValue(obj.getStockPort() == null ? "" : obj.getStockPort());
            row.createCell(1).setCellValue(obj.getStorageNumber() == null ? "" : obj.getStorageNumber());
            row.createCell(2).setCellValue(obj.getGetUnitNumber() == null ? "" : obj.getGetUnitNumber());
            row.createCell(3).setCellValue(obj.getGetUnit() == null ? "" : obj.getGetUnit());
            row.createCell(4).setCellValue(obj.getScattered() == null ? "" : obj.getScattered());
            row.createCell(5).setCellValue(obj.getPeisongTime() == null ? "" : obj.getPeisongTime());
            row.createCell(6).setCellValue(obj.getStorageState() == null ? "" : obj.getStorageState());
            row.createCell(7).setCellValue(obj.getStorageTime() == null ? "" : DateUtil.DateFormat(obj.getStorageTime(),"yyyy-MM-dd HH:mm:ss"));
            row.createCell(8).setCellValue(obj.getStorageCompleteTime() == null ? "" : DateUtil.DateFormat(obj.getStorageCompleteTime(),"yyyy-MM-dd HH:mm:ss"));
            row.createCell(9).setCellValue(obj.getAreaName() == null ? "" : obj.getAreaName());
            row.createCell(10).setCellValue(obj.getPositionNumber() == null ? "" : obj.getPositionNumber());
            row.createCell(11).setCellValue(obj.getGoodsName() == null ? "" : obj.getGoodsName());
            row.createCell(12).setCellValue(obj.getGoodsNumber() == null ? "" : obj.getGoodsNumber());
            row.createCell(13).setCellValue(obj.getGoodsPcode69() == null ? "" : obj.getGoodsPcode69());
            row.createCell(14).setCellValue(obj.getNum() == null ? "" : obj.getNum());
            row.createCell(15).setCellValue(obj.getRealNum() == null ? "" : obj.getRealNum());
            row.createCell(16).setCellValue(obj.getUnit() == null ? "" : obj.getUnit());
            row.createCell(17).setCellValue(obj.getGoodsStorageTime() == null ? "" : obj.getGoodsStorageTime());
            cnt++;
        }

        // 设置响应头
        OutputStream output = response.getOutputStream();
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + new String(("拣货订单及明细" + ".xlsx").getBytes(), "iso-8859-1"));
        // 写入响应
        try (OutputStream excelOutput = output) {
            wb.write(excelOutput);
        }
        wb.close();
    }
}
